package zdream.pmfield.test.stage.timeline;

import org.junit.Before;
import org.junit.Test;

import java.util.List;
import java.util.stream.Collectors;

import zdream.pmfield.data.foe.BStat;
import zdream.pmfield.data.foe.Foe;
import zdream.pmfield.data.foe.FoeTemplate;
import zdream.pmfield.stage.object.FoeActor;
import zdream.pmfield.stage.Stage;
import zdream.pmfield.stage.Timeline;
import zdream.pmfield.storage.FoeTemplateStorage;

import static org.junit.Assert.*;

/**
 * @author Zdream
 * @date 2023-11-13
 * @since 0.0.1
 */
public class TimelineCase {
	FoeTemplateStorage storage;
	Foe foe1, foe2;

	@Before
	public void before() {
		storage = new FoeTemplateStorage();
		storage.load();
	}

	@Test
	public void testCreateStage() {
		final FoeTemplate foe1Template = storage.findFoeById(1);
		final FoeTemplate foe4Template = storage.findFoeById(4);
		assertTrue(foe4Template.bStats[BStat.SP.ordinal()] > foe1Template.bStats[BStat.SP.ordinal()]);

		do {
			foe1 = Foe.builder(foe1Template)
					.withLevel(20)
					.build();
			foe2 = Foe.builder(foe4Template)
					.withLevel(20)
					.build();
		} while (foe2.bStats[BStat.HP.ordinal()] > foe1.bStats[BStat.HP.ordinal()]);

		Stage stage = Stage.builder()
				.putFoeToOneSide(foe1)
				.putFoeToAnotherSide(foe2)
				.withStorage(storage)
				.build();
		System.out.println("Foe 1 speed is " + foe1.bStats[BStat.SP.ordinal()]);
		System.out.println("Foe 2 speed is " + foe2.bStats[BStat.SP.ordinal()]);

		assertTrue(foe2.bStats[BStat.SP.ordinal()] > foe1.bStats[BStat.SP.ordinal()]);
		final FoeActor actor1 = stage.allFoes.stream()
				.filter(foeActor -> foeActor.foe == foe1)
				.findFirst().orElse(null);
		assertNotNull(actor1);
		final FoeActor actor2 = stage.allFoes.stream()
				.filter(foeActor -> foeActor.foe == foe2)
				.findFirst().orElse(null);
		assertNotNull(actor2);

		assertTrue(actor2.speedCost < actor1.speedCost);
		assertTrue(actor2.speedRemains < actor1.speedRemains);
		// 速度最慢的那个 cost 恒为 1
		assertEquals(actor1.speedCost, 1f, 0.001f);

		final List<Timeline.TimelineItem> order = stage.timeline.createOrder()
				.withCount(16)
				.build();
		System.out.println("TimelineItem order is " + order);
		long actor1Count = order.stream()
				.filter(item -> item.asFoe().foe == actor1)
				.count();
		assertNotEquals(actor1Count, 0);
		long actor2Count = order.stream()
				.filter(item -> item.asFoe().foe == actor2)
				.count();
		assertNotEquals(actor2Count, 0);
		assertEquals(actor1Count + actor2Count, 16);
		assertTrue(actor2Count >= actor1Count);

		// 修复不稳定 case: 极端情况下, 小火龙的速度会比妙蛙种子慢
		if (actor1Count == actor2Count) {
			List<Timeline.TimelineItem> order1 = order.stream()
					.filter(item -> item.asFoe().foe == actor1)
					.sorted()
					.collect(Collectors.toList());
			List<Timeline.TimelineItem> order2 = order.stream()
					.filter(item -> item.asFoe().foe == actor2)
					.sorted()
					.collect(Collectors.toList());
			assertTrue(order1.get(1).time - order1.get(0).time > order2.get(1).time - order2.get(0).time);
		}
	}
}
